package com.fowo.api.exportCenter.service.impl;

import com.fowo.api.exportCenter.model.ExportCenterVo;
import com.fowo.api.exportCenter.model.ExportVo;
import com.fowo.api.exportCenter.service.ExportCenterService;
import com.fowo.api.exportCenter.service.ExportCommonService;
import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.sys.service.FileService;
import com.fowo.api.sys.service.SysMessageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

/**
 *  通用导出异步
 */
@Component
@Slf4j
public class ExportCommonServiceImpl implements ExportCommonService {
    @Resource
    private ExportCenterService exportCenterService;
    @Resource
    private FileService fileService;
    @Resource
    private SysMessageService sysMessageService;
    @Value("${spring.servlet.port:8080}")
    private int serverPort;
    @Resource
    private RestTemplate restTemplate;
//    @Override
//    public void export(Map searche, Long userId, ModuleSystemEnum module) throws Exception {
//
//         searche.put("currentUserId",userId);
//        ExportCenterVo entity = new ExportCenterVo();
//        entity.setType("2");
//        entity.setCreateUser(userId);
//        entity.setLastUpdateUser(userId);
//        entity.setName(module.getName());
//        entity.setState("0");
//        Long id= exportCenterService.create(entity);
//        entity.setId(id);
//        try {
//            //从ApplicationContext中取出已创建好的的对象
//            //不可直接反射创建serviceimpi对象，因为反射创建出来的对象无法实例化dao接口
//            ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
//            //反射创建serviceimpi实体对象，和实体类
//            Class<?> ServiceImplType = Class.forName(module.getClazz());
//            //反射设置方法参数。
//            Method method = ServiceImplType.getDeclaredMethod("search",module.getSearch());
//            //在ApplicationContext中根据class取出已实例化的bean
//            //执行对应导出方法
//            List<?>  o= (List<?>) method.invoke(applicationContext.getBean(ServiceImplType), JSON.parseObject(JSON.toJSONString(searche), module.getSearch()));
//            //创建一个流，等待写入excel文件内容
//            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//            JSONArray jsonArray1= JSONArray.parseArray(JSON.toJSONString(o));
//            List<?> list= JSON.parseArray(jsonArray1.toJSONString(), ExportCenterExcelPo.class);
//            //List<?> list= castList(jsonArray1,ExportCenterExcelPo.class);
//            //将excel文件写入byteArrayOutputStream中
//            EasyExcel.write(byteArrayOutputStream, module.getEntity()).sheet("sheet1").doWrite(list);
//            //查询生成的excel文件（byteArrayOutputStream）大小
//            //创建inputStream流
//            InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
//            SysFile sysFile= fileService.upload(module.getName()+".xlsx",".xlsx",inputStream,null,null);
//            entity.setState("1");
//            entity.setFileLink(sysFile.getStorageKey());
//            exportCenterService.update(entity);
//            //通知消息
//            sysMessageService.createSysMessage(userId,"urgent","下载中心","导出成功",sysFile.getStorageKey());
//        }catch (Exception e){
//            e.printStackTrace();
//            entity.setState("2");
//            exportCenterService.update(entity);
//            sysMessageService.createSysMessage(userId,"urgent","下载中心","导出失败",null);
//        }
//
//
//    }
//    @Override
//    public void export(ExportEntityVo exportVo) throws Exception {
//        exportVo.getSearch().put("currentUserId",exportVo.getUserId());
//        ExportCenterVo entity = new ExportCenterVo();
//        entity.setType("2");
//        entity.setCreateUser(exportVo.getUserId());
//        entity.setLastUpdateUser(exportVo.getUserId());
//        entity.setName(exportVo.getModule().getName());
//        entity.setState("0");
//        Long id= exportCenterService.create(entity);
//        entity.setId(id);
//        try {
//            //从ApplicationContext中取出已创建好的的对象
//            //不可直接反射创建serviceimpi对象，因为反射创建出来的对象无法实例化dao接口
//            ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
//            //反射创建serviceimpi实体对象，和实体类
//            Class<?> ServiceImplType = Class.forName(exportVo.getModule().getClazz());
//            //反射设置方法参数。
//            Method method = ServiceImplType.getDeclaredMethod("search",exportVo.getModule().getSearch());
//            //在ApplicationContext中根据class取出已实例化的bean
//            //执行对应导出方法
//            List<?>  o= (List<?>) method.invoke(applicationContext.getBean(ServiceImplType), JSON.parseObject(JSON.toJSONString(exportVo.getSearch()), exportVo.getModule().getSearch()));
//            //创建一个流，等待写入excel文件内容
//            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//            JSONArray jsonArray1= JSONArray.parseArray(JSON.toJSONString(o));
//            List<?> list= JSON.parseArray(jsonArray1.toJSONString(),ExportCenterExcelPo.class);
//            //List<?> list= castList(jsonArray1,ExportCenterExcelPo.class);
//            //将excel文件写入byteArrayOutputStream中
//            EasyExcel.write(byteArrayOutputStream, exportVo.getModule().getEntity()).sheet("sheet1").doWrite(list);
//            //查询生成的excel文件（byteArrayOutputStream）大小
//            //创建inputStream流
//            InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
//            SysFile sysFile= fileService.upload(exportVo.getModule().getName()+".xlsx",".xlsx",inputStream,null,null);
//            entity.setState("1");
//            entity.setFileLink(sysFile.getStorageKey());
//            exportCenterService.update(entity);
//            //通知消息
//            sysMessageService.createSysMessage(exportVo.getUserId(),"urgent","下载中心","导出成功",sysFile.getStorageKey());
//        }catch (Exception e){
//            e.printStackTrace();
//            entity.setState("2");
//            exportCenterService.update(entity);
//            sysMessageService.createSysMessage(exportVo.getUserId(),"urgent","下载中心","导出失败",null);
//        }
//    }
//
//    @Override
//    public void export2(Map search, Long userId, ModuleSystemEnum module,HttpServletResponse response) throws Exception {
//
//
//        //从ApplicationContext中取出已创建好的的对象
//        //不可直接反射创建serviceimpi对象，因为反射创建出来的对象无法实例化dao接口
//        ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
//        //反射创建serviceimpi实体对象，和实体类
//        Class<?> ServiceImplType = Class.forName(module.getClazz());
//        //反射设置方法参数。
//        Method method = ServiceImplType.getDeclaredMethod("export",module.getSearch(),  MockHttpServletResponse.class);
//        //在ApplicationContext中根据class取出已实例化的bean
//        //执行对应导出方法
//        Object o= method.invoke(applicationContext.getBean(ServiceImplType), JSON.parseObject(JSON.toJSONString(search), module.getSearch()),response);
//        //创建一个流，等待写入excel文件内容
//        response.getContentType();
//        OutputStream outputStream= response.getOutputStream();
//        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        byteArrayOutputStream.writeTo(response.getOutputStream());
//        byte[] buffer =byteArrayOutputStream.toByteArray();
//        InputStream inputStream = new ByteArrayInputStream(buffer);
//        String fileName ="D:\\uploads\\test.xlsx";
//        writeToLocal(fileName,inputStream);
//        System.out.println(1);
//
//    }

    @Override
    public void export3(ExportVo exportVo ,Long userId, String token) throws Exception {
        ExportCenterVo entity = new ExportCenterVo();
        entity.setType("2");
        entity.setName(exportVo.getFileName());
        entity.setCreateUser(userId);
        entity.setLastUpdateUser(userId);
        entity.setState("0");
        Long id= exportCenterService.create(entity);
        entity.setId(id);
        try{
            Map map=exportVo.getSearch();
            String search="";
            for(Object key : map.keySet()){
                Object value = map.get(key);
                search=search+key+"="+value+"&" ;
            }
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", token);
            HttpEntity request = new HttpEntity(headers);
            String url = exportVo.getUrl();
            // 转换相对地址为绝对地址
            url = String.format("http://127.0.0.1:%d%s", serverPort, url);
            ResponseEntity<byte[]> responseEntity = restTemplate.exchange(
                    url + "?" + search,
                    HttpMethod.GET,
                    request,
                    byte[].class);
            InputStream inputStream = new ByteArrayInputStream(responseEntity.getBody());
            ContentDisposition contentDisposition = responseEntity.getHeaders().getContentDisposition();
            String fileNames= contentDisposition != null ? contentDisposition.getFilename() : null;
            if (!StringUtils.hasText(fileNames)) {
                fileNames = "未命名的导出文件.xlsx";
            } else {
                fileNames = URLDecoder.decode(fileNames, StandardCharsets.UTF_8);
            }
            SysFile sysFile= fileService.upload(fileNames,".xlsx",inputStream,null,null);
            entity.setState("1");
            entity.setFileLink(sysFile.getStorageKey());
            entity.setName(fileNames.substring(0,fileNames.indexOf(".")));
            entity.setLastUpdateTime(new Date());
            exportCenterService.update(entity);
            //通知消息
            sysMessageService.createSysMessage(userId,"urgent","下载中心","导出成功",sysFile.getStorageKey());
        }catch (Exception e){
            log.error("运行后台导出任务时发生错误", e);
            entity.setState("2");
            entity.setLastUpdateTime(new Date());
            exportCenterService.update(entity);
            sysMessageService.createSysMessage(userId,"urgent","下载中心","导出失败",null);
        }

    }


    /**
     * 文件下载
     * @param destination  下载路径
     * @param input
     * @throws IOException
     */
    public static void writeToLocal(String destination, InputStream input)
            throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        input.close();
        downloadFile.close();

    }
}
